package cn.rengy.isql;

import cn.rengy.isql.lang.SortUtil;
import cn.rengy.lang.CacheService;
import cn.rengy.lang.ObjectTranscoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.domain.PageRequest;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 
 * @author rengy
 *
 */
@Slf4j
public class DbService {

	private Dao dao;

	private NamedSqlDao namedSqlDao;

	private CacheService cacheService;

	private ObjectTranscoder objectTranscoder;

	private GetSqlService getSqlService;

	public DbService(Dao dao, NamedSqlDao namedSqlDao, CacheService cacheService, ObjectTranscoder objectTranscoder, GetSqlService getSqlService) {
		this.dao = dao;
		this.namedSqlDao = namedSqlDao;
		this.cacheService = cacheService;
		this.objectTranscoder = objectTranscoder;
		this.getSqlService = getSqlService;
	}

	/**
	 * 分页查询，不查询总条数
	 * @param sqlname
	 * @param paramMap
	 * @param ascOrDesc
	 * @param orderBy
	 * @return
	 */
	public PageResult<Map<String,Object>> getPageNoCount(String sqlname,Map<String,Object> paramMap,
														 PageRequest page,String ascOrDesc,String orderBy){
		return getPage( true,false, sqlname, paramMap,
				page, 0l,
				ascOrDesc, orderBy);
	}
	public PageResult<Map<String,Object>> getPage(boolean isPaging,PageRequest page,String sqlname,Map<String,Object> paramMap,
												  String ascOrDesc,String orderBy){
		return getPage( isPaging,true, sqlname, paramMap,
				page, 0l,
				ascOrDesc, orderBy);
	}
	public PageResult<Map<String,Object>> getPage(boolean isPaging,PageRequest page,String sqlname,Map<String,Object> paramMap,
												  String ascOrDesc,String orderBy,long totalCount){
		return getPage( isPaging,true, sqlname, paramMap,
				page, totalCount,
		 ascOrDesc, orderBy);
	}

	public PageResult<Map<String,Object>> getPage(boolean isPaging,int pageSize,int pageNumber,String sqlname,Map<String,Object> paramMap,
												  String ascOrDesc,String orderBy,long totalCount){
		PageRequest page=PageRequest.of(pageNumber-1,pageSize);
		return getPage( isPaging,true, sqlname, paramMap,
				page, totalCount,
				ascOrDesc, orderBy);
	}

	public PageResult<Map<String,Object>> getPage(boolean isPaging,boolean isCount,String sqlname,Map<String,Object> paramMap,
												  PageRequest page,long totalCount,
			String ascOrDesc,String orderBy){
		PageResult<Map<String,Object>> pageResult=new PageResult<Map<String,Object>>();
		String orderStr= SortUtil.getOrderSql(orderBy, ascOrDesc);
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlname);
		SqlBuild sqlBuild= getSqlBuild(sqlEntity,sqlParameterSource);
		List<Object> objList=Stream.of(sqlBuild.getParams()).collect(Collectors.toList());
		List<Map<String,Object>> rows=null;
		StringBuilder newSql=new StringBuilder("select * from (");
		newSql.append(sqlBuild.getActualSql()).append(") __t ").append(orderStr);
		if(isPaging){//是否分页
			if(isCount){//是否查询总条数
				if(totalCount<=0){//前端可以传过来，不用再查询 没有实现
					String countSqlid=sqlname.concat("-count");
					totalCount= querySingleColumn(countSqlid, paramMap, Long.class);
				}
				pageResult.setTotal(totalCount);
			}
			if(!isCount || totalCount > 0) {//
				//PageRequest page=PageRequest.of(pageNumber-1,pageSize);
				//Page page=new Page(pageNumber, pageSize, totalCount);
				objList.add(page.getOffset());
				objList.add(page.getPageSize());
				newSql.append(" limit ?,?");
			}
		}
		rows=dao.queryForList(newSql.toString(), objList.toArray());
		if(!isPaging){
			pageResult.setTotal((long)rows.size());
		}
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, rows);
		}
		pageResult.setRows(rows);
		return pageResult;
	}



	
	
	public SqlBuild getSqlBuild(String sqlname,Object args) {
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlname);
		VariableParsedSql parsedSql=sqlEntity.getParsedSql();
		return SqlParser.build(parsedSql, args);
	}
	SqlBuild getSqlBuild(SqlEntity sqlEntity,Object args) {
		VariableParsedSql parsedSql=sqlEntity.getParsedSql();
		return SqlParser.build(parsedSql, args);
	}
	public SqlBuild getSqlBuildBySqlEntity(SqlEntity sqlEntity,Object args) {
		VariableParsedSql parsedSql=sqlEntity.getParsedSql();
		return SqlParser.build(parsedSql, args);
	}

	

	/**
	 * 查询如：List<Long> 
	 */
	public <T> List<T> queryForSingleColumnList(String sqlid, Class<T> elementType,Object... args){
		SqlBuild sqlBuild=getSqlBuild(sqlid,args);
		return  dao.querySingleColumnForList(sqlBuild.getActualSql(),elementType,sqlBuild.getParams());
	}
	public <T> List<T> querySingleColumnForListMapParameter(String sqlid, Map<String,Object> paramMap, Class<T> elementType){
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlBuild sqlBuild=getSqlBuild(sqlid,sqlParameterSource);
		return dao.querySingleColumnForList(sqlBuild.getActualSql(), elementType, sqlBuild.getParams());
		
		
	}
	public List<Map<String,Object>> queryForList(String sqlid,Object... args){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuild(sqlEntity,args);
		List<Map<String,Object>> list=dao.queryForList(sqlBuild.getActualSql(),sqlBuild.getParams());
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, list);
		}
		return list;
	}
	public List<Map<String,Object>> queryForList(boolean isToCamelCase,String sqlid,Object... args){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuild(sqlEntity,args);
		List<Map<String,Object>> list=dao.queryForList(isToCamelCase,sqlBuild.getActualSql(),sqlBuild.getParams());
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, list);
		}
		return list;
	}
	public List<Map<String,Object>> queryForListMapParameter(String sqlid,Map<String,Object> paramMap){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlBuild sqlBuild=getSqlBuild(sqlEntity,sqlParameterSource);
		List<Map<String,Object>> list=dao.queryForList(sqlBuild.getActualSql(), sqlBuild.getParams());
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, list);
		}
		return list;
	}
	public List<Map<String,Object>> queryForListMapParameter(boolean isToCamelCase,String sqlid,Map<String,Object> paramMap){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlBuild sqlBuild=getSqlBuild(sqlEntity,sqlParameterSource);
		List<Map<String,Object>> list=dao.queryForList(isToCamelCase,sqlBuild.getActualSql(), sqlBuild.getParams());
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, list);
		}
		return list;
	}
	public List<Map<String,Object>> queryForListBeanParameter(String sqlid,Object paramBean){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		_BeanPropertySqlParameterSource sqlParameterSource=new _BeanPropertySqlParameterSource(paramBean);
		SqlBuild sqlBuild=getSqlBuild(sqlEntity,sqlParameterSource);
		List<Map<String,Object>> list=dao.queryForList( sqlBuild.getActualSql(), sqlBuild.getParams());
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, list);
		}
		return list;
	}
	
	public Number updateReturnGeneratedKeys(String sqlid,Object... args){
		SqlBuild sqlBuild=getSqlBuild(sqlid,args);
		Number i= dao.updateReturnGeneratedKeys(sqlBuild.getActualSql(), sqlBuild.getParams());
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		removeCache(sqlEntity, args);
		return i;
	}
	
	public Number updateReturnIdBeanParameter(String sqlid,Object paramBean){
		_BeanPropertySqlParameterSource sqlParameterSource=new _BeanPropertySqlParameterSource(paramBean);
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuildBySqlEntity(sqlEntity,sqlParameterSource);
		Number i= dao.updateReturnGeneratedKeys(sqlBuild.getActualSql(), sqlBuild.getParams());
		removeCache( sqlEntity, sqlParameterSource);
		return i;
	}
	
	public <T> List<T> queryForBeanListBeanParameter(String sqlid, Object paramBean, Class<T> elementType){
		_BeanPropertySqlParameterSource sqlParameterSource=new _BeanPropertySqlParameterSource(paramBean);
		SqlBuild sqlBuild=getSqlBuild(sqlid,sqlParameterSource);
		return dao.queryForBeanList(sqlBuild.getActualSql(),elementType, sqlBuild.getParams());
	}
	public <T> List<T> queryForBeanList(String sqlid, Class<T> elementType, Object... args){
		SqlBuild sqlBuild=getSqlBuild(sqlid,args);
		return dao.queryForBeanList(sqlBuild.getActualSql(),elementType, sqlBuild.getParams());
	}
	public <T> List<T> queryForBeanListMapParameter(String sqlid, Map<String,Object> paramMap, Class<T> elementType){
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlBuild sqlBuild=getSqlBuild(sqlid,sqlParameterSource);
		
		return dao.queryForBeanList(sqlBuild.getActualSql(), elementType, sqlBuild.getParams());
	}
	
	
	public Map<String,Object> queryForMap(String sqlid,Object... args){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuild(sqlEntity,args);
		Map<String,Object> map =dao.queryForMap(sqlBuild.getActualSql(), sqlBuild.getParams());
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, map);
		}
		return map;
	}
	public Map<String,Object> queryForMap(boolean isToCamelCase,String sqlid,Object... args){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuild(sqlEntity,args);
		Map<String,Object> map =dao.queryForMap(isToCamelCase,sqlBuild.getActualSql(), sqlBuild.getParams());
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, map);
		}
		return map;
	}
	
	public int update(String sqlid,Object... args){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuildBySqlEntity(sqlEntity ,args);
		int i= dao.update(sqlBuild.getActualSql(), sqlBuild.getParams());
		removeCache(sqlEntity,args);
		return i;
	}
	
	
	
	public int updateBeanParameter(String sqlid,Object paramBean){
		_BeanPropertySqlParameterSource _BeanPropertySqlParameterSource=new _BeanPropertySqlParameterSource(paramBean);
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuildBySqlEntity(sqlEntity ,_BeanPropertySqlParameterSource);
		int i= dao.update(sqlBuild.getActualSql(), sqlBuild.getParams());
		removeCache( sqlEntity, _BeanPropertySqlParameterSource);
		return i;
	}
	
	public <T> T queryForBean(String sqlid,Class<T> elementType,Object... args){
		SqlBuild sqlBuild=getSqlBuild(sqlid,args);
		return dao.queryForBean(sqlBuild.getActualSql(), elementType, sqlBuild.getParams());
	}
	public <T> T queryForBeanMapParameter(String sqlid,Map<String,Object> paramMap,Class<T> elementType){
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlBuild sqlBuild=getSqlBuild(sqlid,sqlParameterSource);
		return dao.queryForBean(sqlBuild.getActualSql(), elementType,sqlBuild.getParams());
	}
	public Map<String,Object> queryForMapParameter(String sqlid,Map<String,Object> paramMap){
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlEntity sqlEntity=this.getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuild(sqlEntity,sqlParameterSource);
		
		Map<String,Object> map =dao.queryForMap(sqlBuild.getActualSql(), sqlBuild.getParams());
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, map);
		}

		return map;
	}
	public Map<String,Object> queryForMapParameter(boolean isToCamelCase,String sqlid,Map<String,Object> paramMap){
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlEntity sqlEntity=this.getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuild(sqlEntity,sqlParameterSource);

		Map<String,Object> map =dao.queryForMap(isToCamelCase,sqlBuild.getActualSql(), sqlBuild.getParams());
		String transcode=sqlEntity.getTranscode();
		if(StringUtils.hasLength(transcode)){
			objectTranscoder.transcode(transcode, map);
		}

		return map;
	}
	public int updateMapParameter(String sqlid,Map<String,Object> paramMap){
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuildBySqlEntity(sqlEntity,sqlParameterSource);
		int i= dao.update(sqlBuild.getActualSql(), sqlBuild.getParams());
		removeCache( sqlEntity, sqlParameterSource);
		return i;
	}
	@Transactional(rollbackFor = Exception.class)
	public int[] updates(String sqlid,Map<String,Object> paramMap){
		List<Map<String,Object>> list=this.queryForList("select_sqllist_likename", sqlid.concat("%"));
		Assert.notNull(list, "sql must not be null");
		int[] i=new int[list.size()];
		for(int j=0;j<list.size();j++){
			Map<String,Object> map=list.get(j);
			String sqlname=(String)map.get("sqlName");
			i[j]=this.updateMapParameter(sqlname, paramMap);
		}
		return i;
	}
	@Transactional(rollbackFor = Exception.class)
	public int[] updates(String sqlid,Object... args){
		List<Map<String,Object>> list=this.queryForList("select_sqllist_likename", sqlid+"%");
		Assert.notNull(list, "sql must not be null");
		int[] i=new int[list.size()];
		for(int j=0;j<list.size();j++){
			Map<String,Object> map=list.get(j);
			String sqlname=(String)map.get("sqlName");
			//String sqlvalue=(String)map.get("sqlValue");
			i[j]=this.update(sqlname, args);
		}
		return i;
	}
	
	/**
	 * 返回更新记录主键
	 */
	public Number updateReturnGeneratedKeys(String sqlid,Map<String,Object> paramMap){
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		SqlBuild sqlBuild=getSqlBuildBySqlEntity(sqlEntity,sqlParameterSource);
		Number i= dao.updateReturnGeneratedKeys(sqlBuild.getActualSql(), sqlBuild.getParams());
		removeCache( sqlEntity, sqlParameterSource);
		return i;
	}
	private void removeCache(SqlEntity sqlEntity,Object parameter) {
		if(cacheService!=null){
			Integer is_cache=sqlEntity.getIs_remove_cache();
			if(is_cache!=null&& is_cache ==1){
				String cache_name=sqlEntity.getCache_name();
				String cache_operate=sqlEntity.getCache_operate();
				String cacheType=sqlEntity.getCache_type();
				String sqlType=sqlEntity.getSql_type();
				String cache_key_param=sqlEntity.getCache_key_param();
				Integer cache_key_index=sqlEntity.getCache_key_index();
				//String parameterType=null;
				//Object parameterValue=parameter;
				//if(parameter instanceof SqlParameterSource){
				//	parameterType="SqlParameterSource";
					//parameterValue=((SqlParameterSource)parameter).getValue(cache_key_param);
				//}

				CacheManager cacheManager=null;
				if("service".equals(cacheType)) {
//					try {
//						Object service=  getBean(cache_name);
//						Method method= ReflectUtil.getMethodByName(service.getClass(), cache_key_param);
//						method.invoke(service);
//					} catch (Exception e) {
//						log.error(ExceptionPrintUtils.getTrace(e));
//					}
				}else{
					if("local".equals(cacheType)) {
						cacheManager= cacheService.getLocalCacheManager();
					}else if("redis".equals(cacheType)) {
						cacheManager=cacheService.getRedisCacheManager();
					}
					if(cacheManager!=null){
						Cache cache=cacheManager.getCache(cache_name);
						if("evict".equals(cache_operate)&&cache!=null){
							if(parameter instanceof SqlParameterSource ) {
								//SqlParameterSource _parameter=(SqlParameterSource)parameter;
								Object keyObj=((SqlParameterSource)parameter).getValue(cache_key_param);
								if(keyObj!=null){
									if(keyObj instanceof Collection){
										Iterator<Object> it=((Collection) keyObj).iterator();
										while(it.hasNext()){
											Object key=it.next();
											cache.evict(key.toString());
											log.info("移除{}缓存,name={},key={}",cacheType,cache_name,key);
										}
									}else{
										log.info("移除{}缓存,name={},key={}",cacheType,cache_name,keyObj);
										cache.evict(keyObj.toString());
									}
								}else{
									log.warn("keyObj is null");
								}
							}else if(sqlType.equals("prepared")) {
								Object[] args=(Object[])parameter;
								if(args!=null&&args.length>0) {
									Object keyObj=args[cache_key_index];
									cache.evict(keyObj);
									log.info("移除{}缓存,name={},key={}",cacheType,cache_name,keyObj);
								}
							}
						}else if("clear".equals(cache_operate)){
							if(cache!=null){
								cache.clear();
								log.info("清空{}缓存：{}",cacheType,cache_name);
							}
						}
					}
				}
			}
		}
	}
	/**
	 * 批量更新
	 */
	public int[] batchUpdate(String sqlid,List<Object[]> batchArgs){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		return this.dao.batchUpdate(sqlEntity.getSql_value(), batchArgs);
	}
	/**
	 * 调用例子：
	 * Map<String, Object>[] batchValues=new Map[insertList.size()];
	 * 				for(int i=0;i<insertList.size();i++){
	 * 					Long file_item_id=insertList.get(i);
	 * 					Long id=IdGenerator.nextId();
	 * 					batchValues[i]=new HashMap<String,Object>(5,1);
	 * 					batchValues[i].put("file_item_id", file_item_id);
	 * 					batchValues[i].put("file_id", fileId);
	 * 					batchValues[i].put("target_id", targetId);
	 * 					batchValues[i].put("order_no", i);
	 * 					batchValues[i].put("id",id );
	 * 					list.add(id);
	 * 				                }
	 * 				this.dbService.batchUpdate("insert_sys_pub_file_item_target_rel", batchValues);
	 */
	public int[] batchUpdate(String sqlid,Map<String, Object>[] valueMaps){
		SqlParameterSource[] sqlParameterSource =this.createBatch(valueMaps);
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		String sqlValue=sqlEntity.getSql_value();
		//String engine_type=sqlEntity.getEngine_type();
		//具名批量update不支持可变参数
//		if(SqlParsingEngine.DIY.toString().equals(engine_type)) {
//			for(SqlParameterSource sps:sqlParameterSource){
//				
//				sqlValue=ParseSqlUtils.parseSql(sqlValue,sps);
//				
//			}
//		}
		return this.namedSqlDao.batchUpdate(sqlValue, sqlParameterSource);
	}
	public int[] batchUpdateBeanParameter(String sqlid,Collection<?> candidates){
		//SqlParameterSourceUtils.createBatch(candidates);
		SqlParameterSource[] sqlParameterSource =this.createBatch(candidates);
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		String sqlValue=sqlEntity.getSql_value();
		//具名批量update不支持可变参数
		return this.namedSqlDao.batchUpdate(sqlValue, sqlParameterSource);
	}
	
	public <T> T querySingleColumn(String sqlid,Class<T> requiredType,Object... args){
		SqlBuild sqlBuild=getSqlBuild(sqlid,args);
		return dao.querySingleColumn(sqlBuild.getActualSql(), requiredType, sqlBuild.getParams());
	}
	//MapParameter
	public <T> T querySingleColumn(String sqlid,Map<String,Object> paramMap,Class<T> requiredType){
		_MapSqlParameterSource sqlParameterSource=new _MapSqlParameterSource(paramMap);
		SqlBuild sqlBuild=getSqlBuild(sqlid,sqlParameterSource);
		return dao.querySingleColumn(sqlBuild.getActualSql(), requiredType, sqlBuild.getParams());
	}
	/**
	 * 更新blob字段
	 */
	public void updateBlobAsBytes(String sqlid,Object... args){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		String sqlValue=sqlEntity.getSql_value();
		this.dao.updateBlobAsBytes(sqlValue, args);
	}
	/**
	 * 更新blob字段
	 */
	public void updateBlobAsBinaryStream(String sqlid,int paramIndex,int contentLength,Object... args){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		String sqlValue=sqlEntity.getSql_value();
		this.dao.updateBlobAsBinaryStream(sqlValue, paramIndex,contentLength, args);
	}
//	public void update2BlobAsBinaryStream(String sqlid,int paramIndex,int contentLength,int param2Index,int content2Length,Object... args){
//		SqlEntity sqlEntity=dbSqlValueService.getSqlEntityByName(sqlid);
//		String sqlValue=sqlEntity.getSql_value();
//		this.dao.update2BlobAsBinaryStream( sqlValue, paramIndex, contentLength, param2Index, content2Length, args);
//	}
	public void getBlobAsBinaryStream(OutputStream outputStream,String sqlid,Object... args){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		String sqlValue=sqlEntity.getSql_value();
		this.dao.getBlobAsBinaryStream(outputStream, sqlValue, args);
	}
	public byte[] getBlobAsBytes(String sqlid,Object... args){
		SqlEntity sqlEntity= getSqlService.getSqlEntityByName(sqlid);
		String sqlValue=sqlEntity.getSql_value();
		return this.dao.getBlobAsBytes(sqlValue,args);
	}
	
	@SuppressWarnings("unchecked")
	private  SqlParameterSource[] createBatch(Collection<?> candidates) {
		SqlParameterSource[] batch = new SqlParameterSource[candidates.size()];
		int i = 0;
		for (Object candidate : candidates) {
			batch[i] = (candidate instanceof Map ? new _MapSqlParameterSource((Map<String, ?>) candidate) :
					new _BeanPropertySqlParameterSource(candidate));
			i++;
		}
		return batch;
	}

	
	private  SqlParameterSource[] createBatch(Map<String, ?>[] valueMaps) {
		SqlParameterSource[] batch = new SqlParameterSource[valueMaps.length];
		for (int i = 0; i < valueMaps.length; i++) {
			batch[i] = new _MapSqlParameterSource(valueMaps[i]);
		}
		return batch;
	}
}
